package com.nineclock.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSSClient;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.utils.CurrentUserHolder;
import com.nineclock.system.dto.SysChangeMainManagerDTO;
import com.nineclock.system.dto.SysCompanyDTO;
import com.nineclock.system.mapper.SysCompanyMapper;
import com.nineclock.system.mapper.SysCompanyUserRoleMapper;
import com.nineclock.system.mapper.SysRoleMapper;
import com.nineclock.system.pojo.SysCompany;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysCompanyUserRole;
import com.nineclock.system.pojo.SysRole;
import com.nineclock.system.service.SysCompanyService;
import com.nineclock.system.service.SysCompanyUserService;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;

@Transactional
@Service
public class SysCompanyServiceImpl extends ServiceImpl<SysCompanyMapper, SysCompany> implements SysCompanyService {


    @Override
    public SysCompany findInfo() {
        //TODO 判断用户登录情况

        //1. 根据登录用户获取公司ID
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //2.通过公司ID查询公司信息
        SysCompany sysCompany = this.getById(companyId);

        //3.如果公司不存在则抛出异常
        if(sysCompany==null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        //4.返回非空公司信息
        return sysCompany;
    }

    @Lazy
    @Autowired
    private OSSClient ossClient;

    @Autowired
    private OssProperties ossProperties;

    @Override
    public String uploadOSS(MultipartFile file) {

        //TODO 判断用户登录情况

        //1. 检验文件合法性
        //1.1 检查文件内容是否为空
        if(file==null || file.isEmpty()){
            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }

        //1.2 检查文件类型是否符合要求
        String type = file.getContentType();
        if(!NcConstant.ALLOWED_IMG_TYPES.contains(type)){
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        //1.3 检查文件大小是否超过限制
        long size = file.getSize();
        if(size> NcConstant.maxFileSize){
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }

        //2.生成唯一文件名
        String dateStr = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS");
        String fileName = dateStr +file.getOriginalFilename();

        //3.执行上传
        try {
            /**
             * 参数1：  桶名
             * 参数2：  文件名
             * 参数3： 上传文件的输入流
             */
            ossClient.putObject(ossProperties.getBucketName(),fileName,file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }


        //4.响应logo的url访问地址
        String url = String.format(ossProperties.getHost(),ossProperties.getBucketName()) +  fileName;

        return url;
    }

    @Override
    public void updateInfo(SysCompanyDTO dto) {
        //TODO 判断用户登录情况

        //1.判断参数合法性
        if(dto==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //2.根据ID查询企业信息
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompany sysCompany = this.getById(companyId);

        //3.如果不存在则抛异常
        if(sysCompany==null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        //4.设置要更新的值
        SysCompany sysCompanyDB = new SysCompany();
        sysCompanyDB.setId(companyId);
        sysCompanyDB.setLogo(dto.getLogo()); //logo的URL地址
        sysCompanyDB.setName(dto.getName()); //公司名称

        //5.执行更新
        this.updateById(sysCompanyDB);
    }



















    @Autowired
    private SysCompanyUserService sysCompanyUserService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysCompanyUserRoleMapper sysCompanyUserRoleMapper;

    @Override
    public void changeSysAdmin(SysChangeMainManagerDTO dto) {
        //1.判断参数合法性
        if(dto==null || StrUtil.isEmpty(dto.getCode()) || dto.getUserId()==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        Long companyId = CurrentUserHolder.get().getCompanyId();
        long companyUserId = CurrentUserHolder.get().getCompanyUserId();
        Long companyUserIdNew = dto.getUserId(); //新的管理员公司用户ID

        //2.根据新用户ID查询是否存在
        SysCompanyUser sysCompanyUser = sysCompanyUserService.getById(companyUserIdNew);
        if(sysCompanyUser==null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        //3.判断验证码是否正确
        String redisKey  = SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX + sysCompanyUser.getMobile();
        String redisCode = (String)redisTemplate.boundValueOps(redisKey).get();
        if(!redisCode.equals(dto.getCode())){
            throw new NcException(ResponseEnum.INVALID_VERIFY_CODE);
        }

        //4.根据公司ID查询角色
        LambdaQueryWrapper<SysRole> lambdaQueryWrapperForRole = new LambdaQueryWrapper();
        lambdaQueryWrapperForRole.eq(SysRole::getCompanyId, companyId);
        lambdaQueryWrapperForRole.eq(SysRole::getRoleName, "ROLE_ADMIN_SYS");
        SysRole sysRole = sysRoleMapper.selectOne(lambdaQueryWrapperForRole);
        Long roleId = sysRole.getId();


        //5.删除旧的管理员与公司的关系
        LambdaQueryWrapper<SysCompanyUserRole> lambdaQueryWrapperForDelete = new LambdaQueryWrapper<>();
        lambdaQueryWrapperForDelete.eq(SysCompanyUserRole::getCompanyId, companyId);
        lambdaQueryWrapperForDelete.eq(SysCompanyUserRole::getCompanyUserId, companyUserId);
        lambdaQueryWrapperForDelete.eq(SysCompanyUserRole::getRoleId, roleId);
        sysCompanyUserRoleMapper.delete(lambdaQueryWrapperForDelete);


        //6.添加新管理员与公司的关系
        SysCompanyUserRole sysCompanyUserRole = new SysCompanyUserRole();
        sysCompanyUserRole.setCompanyId(companyId);
        sysCompanyUserRole.setRoleId(roleId);
        sysCompanyUserRole.setCompanyUserId(dto.getUserId());
        sysCompanyUserRoleMapper.insert(sysCompanyUserRole);

        //7.删除redis
        redisTemplate.delete(redisKey);
    }

}
